<?php
// 需要预定义 UNIQID (高并发时区分不同客户端的请求, 跟踪id)
class FileLog
{
    public static $instance = null;

    public static $uuid = ''; //追踪日志用唯一字符串
    public static $message = '';
    public static $tag = '';
    public static $level = '';
    public static $separator = "\t";

    private $middleDir = '';
    private $fileName = '';
    private $filePath = ''; //日志文件完整路径

    private function __construct(){}

    /**
     * @param array|string $dir 要写入的目录
     * @param string $file 文件名, 默认为当天的日期
     * @return $this
     */
    public static function ini($dir='info', $file='')
    {
        if (empty(self::$instance)) {
            self::$instance = new self();
        }

        self::$instance->createDir($dir, $file);

        return self::$instance;
    }

    private function createDir($dir, $file)
    {
        $this->middleDir = is_array($dir) ? implode('/', $dir) : $dir;
        $this->fileName = empty($file) ? REQUEST_DAY : $file;

        $this->middleDir = str_replace('\\', '/', $this->middleDir);
        $this->fileName = str_replace('\\', '/', $this->fileName);

        $this->middleDir = trim($this->middleDir, '/');
        $this->fileName = trim($this->fileName, '/');
        
        $prefix = rtrim(LOGPATH, '/');
        $this->filePath = $prefix.'/'.$this->middleDir.'/'.$this->fileName.'.log';
        
        //创建目录
        if (file_exists(self::$instance->filePath) === FALSE) {
            if (!mkdir(self::$instance->filePath, 0766, true)) {
                file_put_contents($prefix.'/error.log', "创建日志目录失败: $this->filePath", FILE_APPEND ); //追加模式
            }
        }
        
        return $this;
    }
    
    /**
     * 记录日志
     * @return FileLog
     */
    private static function log()
    {
        if (is_array(self::$message) || is_object(self::$message)) {
            $msg = json_encode(self::$message, JSON_UNESCAPED_UNICODE); //汉字原样显示, 不显示成编码格式
        } else {
            $msg = self::$message;
        }

        //日志文件
        $filePath = rtrim(LOGPATH, '/').'/'.REQUEST_DAY.'.log';

        //时间
        $datetime = date('Y-m-d H:i:s');
        $microTime = explode('.', microtime(true));
        $microSec = end($microTime);

        //跟踪ID, 便于跨系统查询
        $uuid = empty(self::$uuid) ? UNIQID : self::$uuid;

        //调用者
        $arr = debug_backtrace(2, 1);
        $caller = '';
        if (!empty($arr[0])) {
            $caller = basename($arr[0]['file']).'_'.$arr[0]['line'];
        }
        
        //日志内容
        $arr = [$datetime.'.'.$microSec, $uuid, self::$level, self::$tag, $msg, $caller];
        $string = implode(self::$separator, $arr).PHP_EOL;

        file_put_contents($filePath, $string, FILE_APPEND ); //追加模式

        self::$message = '';
        self::$tag = '';
        self::$level = '';

        return self::class;
    }

    public static function error($msg, $tag='')
    {
        if (LOG_LEVEL >= 1) {
            self::$message = $msg;
            self::$tag = $tag;
            self::$level = 'error';
            return self::log();
        }
        return self::class;
    }

    public static function warning($msg, $tag='')
    {
        if (LOG_LEVEL >= 2) {
            self::$message = $msg;
            self::$tag = $tag;
            self::$level = 'warning';
            return self::log();
        }
        return self::class;
    }

    public static function notice($msg, $tag='')
    {
        if (LOG_LEVEL >= 3) {
            self::$message = $msg;
            self::$tag = $tag;
            self::$level = 'notice';
            return self::log();
        }
        return self::class;
    }

    public static function debug($msg, $tag='')
    {
        if (LOG_LEVEL >= 4) {
            self::$message = $msg;
            self::$tag = $tag;
            self::$level = 'debug';
            return self::log();
        }
        return self::class;
    }

    public static function info($msg, $tag='')
    {
        self::$message = $msg;
        self::$tag = $tag;
        self::$level = 'info';
        self::log();
        return self::class;
    }
}
